# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1496.1.6 -> 1.1496.1.7 # arch/ia64/Kconfig 1.38.1.10 -> 1.38.1.11 # arch/ia64/lib/Makefile 1.22 -> 1.23 # (new) -> 1.1 arch/ia64/lib/dec_and_lock.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/12/10 davidm@tiger.hpl.hp.com 1.1499 # Merge tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/linux-ia64-2.5 # -------------------------------------------- # 03/12/11 davidm@tiger.hpl.hp.com 1.1496.1.7 # ia64: Based on patch by Jerome Marchand: Add ia64-optimized # atomic_dec_and_lock(). Actually, this could be the generic # version for any platform that has cmpxchg(). # -------------------------------------------- # diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Sun Dec 14 00:40:13 2003 +++ b/arch/ia64/Kconfig Sun Dec 14 00:40:13 2003 @@ -375,6 +375,11 @@ depends on IA32_SUPPORT default y +config HAVE_DEC_LOCK + bool + depends on (SMP || PREEMPT) + default y + config PERFMON bool "Performance monitor support" help diff -Nru a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile --- a/arch/ia64/lib/Makefile Sun Dec 14 00:40:13 2003 +++ b/arch/ia64/lib/Makefile Sun Dec 14 00:40:13 2003 @@ -13,6 +13,7 @@ lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o lib-$(CONFIG_MD_RAID5) += xor.o +lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED diff -Nru a/arch/ia64/lib/dec_and_lock.c b/arch/ia64/lib/dec_and_lock.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/lib/dec_and_lock.c Sun Dec 14 00:40:13 2003 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2003 Jerome Marchand, Bull S.A. + * Cleaned up by David Mosberger-Tang + * + * This file is released under the GPLv2, or at your option any later version. + * + * ia64 version of "atomic_dec_and_lock()" using the atomic "cmpxchg" instruction. This + * code is an adaptation of the x86 version of "atomic_dec_and_lock()". + */ + +#include +#include +#include +#include + +/* + * Decrement REFCOUNT and if the count reaches zero, acquire the spinlock. Both of these + * operations have to be done atomically, so that the count doesn't drop to zero without + * acquiring the spinlock first. + */ +int +atomic_dec_and_lock (atomic_t *refcount, spinlock_t *lock) +{ + int old, new; + + do { + old = atomic_read(refcount); + new = old - 1; + + if (unlikely (old == 1)) { + /* oops, we may be decrementing to zero, do it the slow way... */ + spin_lock(lock); + if (atomic_dec_and_test(refcount)) + return 1; + spin_unlock(lock); + return 0; + } + } while (cmpxchg(&refcount->counter, old, new) != old); + return 0; +} + +EXPORT_SYMBOL(atomic_dec_and_lock);